﻿using DrawControl.UI.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DrawControl.UI.View
{
    public class UploadControl : Control
    {
        private Image _image;
        public UploadControl()
        {
            this.SetStyle(
             ControlStyles.UserPaint |  //控件自行绘制，而不使用操作系统的绘制
             ControlStyles.AllPaintingInWmPaint | //忽略背景擦除的Windows消息，减少闪烁，只有UserPaint设为true时才能使用。
             ControlStyles.OptimizedDoubleBuffer |//在缓冲区上绘制，不直接绘制到屏幕上，减少闪烁。
             ControlStyles.ResizeRedraw | //控件大小发生变化时，重绘。                  
             ControlStyles.SupportsTransparentBackColor, //支持透明背景颜色
             true);

            _image =Properties.Resources.upload;
            this.Cursor = Cursors.Hand;
            this.AllowDrop = true;
            this.Text = "Drop file here or click to upload";
        }
        private uint _radius = 10;
        [Category("高级"), DefaultValue(10), Description("圆角")]
        public uint Radius
        {
            get=> _radius;
            set
            {
                _radius = value;
                this.Invalidate();
            }
        }
        private uint _border = 2;
        [Category("高级"), DefaultValue(2), Description("边框大小")]
        public uint Border
        {
            get=> _border;
            set
            {
                if (value >= Radius) return;
                _border = value;
                this.Invalidate();
            }
        }
        private Color _borderColor= Color.Silver;
        [Category("高级"), DefaultValue(typeof(Color), "Color.Silver"), Description("边框标准颜色")]
        public Color BorderNormalColor
        {
            get => _borderColor;
            set
            {
                _borderColor = value;
                this.Invalidate();
            }
        }
        private DashStyle _borderStyle= DashStyle.Dash;
        [Category("高级"), DefaultValue(typeof(DashStyle), "DashStyle.Dash"), Description("边框线样式")]
        public DashStyle BorderStyle
        {
            get=>_borderStyle;
            set
            {
                _borderStyle = value;
                this.Invalidate();
            }
        }
        private Color _borderPressedColor = Color.FromArgb(121, 187, 255);
        [Category("高级"), DefaultValue(typeof(Color), "121, 187, 255"), Description("边框鼠标按下颜色")]
        public Color BorderPressedColor
        {
            get
            {
                return this._borderPressedColor;
            }
            set
            {
                this._borderPressedColor = value;
                this.Invalidate();
            }
        }
        private Color _borderHoverColor = Color.FromArgb(121, 187, 255);
        [Category("高级"), DefaultValue(typeof(Color), "121, 187, 255"), Description("边框鼠标经过颜色")]
        public Color BorderHoverColor
        {
            get
            {
                return this._borderHoverColor;
            }
            set
            {
                this._borderHoverColor = value;
                this.Invalidate();
            }
        }
        private ControlState ColorState { get; set; }= ControlState.Normal;
        protected override void OnMouseEnter(EventArgs e)//鼠标进入时
        {
            ColorState = ControlState.Hover;//Hover
            this.Invalidate();
            base.OnMouseEnter(e);
        }
        protected override void OnMouseLeave(EventArgs e)//鼠标离开
        {
            ColorState = ControlState.Normal;//正常
            this.Invalidate();
            base.OnMouseLeave(e);
        }
        protected override void OnMouseDown(MouseEventArgs e)//鼠标按下
        {
            if (e.Button == MouseButtons.Left && e.Clicks == 1)//鼠标左键且点击次数为1
            {
                ColorState = ControlState.Pressed;//按下的状态
                this.Invalidate();
                using OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.Filter = "所有文件 (*.*)|*.*";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    FilesCallback?.Invoke(new string[] { openFileDialog.FileName });
                }
            }
            base.OnMouseDown(e);
        }
        protected override void OnMouseUp(MouseEventArgs e)//鼠标弹起
        {
            if (e.Button == MouseButtons.Left && e.Clicks == 1)
            {
                if (ClientRectangle.Contains(e.Location))//控件区域包含鼠标的位置
                {
                    ColorState = ControlState.Hover;
                }
                else
                {
                    ColorState = ControlState.Normal;
                }
                this.Invalidate();
            }
            base.OnMouseUp(e);
        }
        [Browsable(true)]
        private string _text;
        public override string Text
        {
            get => _text;
            set
            {
                _text = value;
                this.Invalidate();
            }
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            e.Graphics.Smooth();

            // 绘制圆角背景
            Rectangle outRect = new Rectangle(0, 0, this.Width, this.Height);
            using var outPath = GetRoundedRectPath(outRect, Radius);
            //this.Region = new Region(outPath);// 与此控件关联的区域，有锯齿
            using SolidBrush b = new SolidBrush(this.BackColor);
            e.Graphics.FillPath(b, outPath);

            uint border = Border;
            if (ColorState == ControlState.DragEnter)
            {
                border += 1;
                if (border >= Radius)
                    border -= 1;
            }
            // 绘制圆角边框
            var innerRect = Rectangle.Inflate(outRect, -(int)border, -(int)border);
            using GraphicsPath innerPath = GetRoundedRectPath(innerRect, Radius - border);
            using Pen pen = new Pen(ColorState switch
            {
                ControlState.Hover => this.BorderHoverColor,
                ControlState.Pressed => this.BorderPressedColor,
                ControlState.DragEnter => this.BorderHoverColor,
                _ => this.BorderNormalColor,
            }, border);
            pen.DashStyle = BorderStyle;
            e.Graphics.DrawPath(pen, innerPath);

            const int h = 5;
            SizeF sizeF = SizeF.Empty;
            if (!string.IsNullOrWhiteSpace(Text))
                sizeF = e.Graphics.MeasureString(Text, this.Font);
            if (_image != null)
            {
                int imageH = 0;
                if (sizeF != SizeF.Empty)
                {
                    imageH = (int)((this.Height - _image.Height - h - sizeF.Height) / 2);
                    TextRenderer.DrawText(e.Graphics, Text, this.Font, new Point((int)((this.Width - sizeF.Width) / 2), imageH + _image.Height + h), this.ForeColor);
                }
                else
                    imageH = this.Height - _image.Height >> 1;
                e.Graphics.DrawImage(_image, this.Width - _image.Width >> 1, imageH);
            }
            else
            {
                if (sizeF != SizeF.Empty)
                {
                    TextRenderer.DrawText(e.Graphics, Text, this.Font, new Point((int)((this.Width - sizeF.Width) / 2), (int)((this.Height - sizeF.Height) / 2)), this.ForeColor);
                }
            }
        }
        /// <summary>
        /// 根据矩形区域rect，计算呈现radius圆角的Graphics路径
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        private GraphicsPath GetRoundedRectPath(Rectangle rect, uint radius)
        {
            int r = (int)radius << 1;
            Rectangle arcRect = new Rectangle(rect.Location, new Size(r, r));
            GraphicsPath path = new GraphicsPath();
            path.AddArc(arcRect, 180, 90);
            // 右上圆弧
            arcRect.X = rect.Right - r;
            path.AddArc(arcRect, 270, 90);
            // 右下圆弧
            arcRect.Y = rect.Bottom - r;
            path.AddArc(arcRect, 0, 90);
            // 左下圆弧
            arcRect.X = rect.Left;
            path.AddArc(arcRect, 90, 90);
            path.CloseFigure();
            return path;
        }
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
        }

        protected override void OnDragEnter(DragEventArgs drgevent)
        {
            base.OnDragEnter(drgevent);
            if (drgevent.Data.GetDataPresent(DataFormats.FileDrop))
                drgevent.Effect = DragDropEffects.Copy;
            else
                drgevent.Effect = DragDropEffects.None;
            ColorState = ControlState.DragEnter;
            this.Invalidate();
        }
        protected override void OnDragLeave(EventArgs e)
        {
            base.OnDragLeave(e);
            ColorState = ControlState.Normal;
            this.Invalidate();
        }
        protected override void OnDragDrop(DragEventArgs drgevent)
        {
            base.OnDragDrop(drgevent);
            ColorState = ControlState.Normal;
            this.Invalidate();
            object? obj = drgevent.Data?.GetData(DataFormats.FileDrop);
            if (obj == null) return;

            FilesCallback?.Invoke((string[])obj);
        }
        public event Action<string[]> FilesCallback;
    }
    public enum ControlState { Hover, Normal, Pressed, DragEnter }
}
